import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse } from '@angular/common/http';
import { Injectable, Injector } from '@angular/core';
import { CacheService } from '@delon/cache';
import { _HttpClient } from '@delon/theme';
import { environment } from '@env/environment';
import { NzMessageService } from 'ng-zorro-antd/message';
import { Observable, Observer } from 'rxjs';

/**
 * 对有收费相关的地址进行拦截，加入收费营业厅ID
 */
@Injectable()
export class HallIDInterceptor implements HttpInterceptor {
    constructor(private injector: Injector) {}

    /**
     * 需要添加拦截的地址
     */
    private urls: RegExp[] = [
        /\/customer\/openAccount/,
        /\/customer\/changeMeter/,
        /\/customer\/remove/,
        /\/customer\/reopenAccount/,
        /\/customer\/stopAccount/,
        /\/customer\/transferOwnership/,
        /\/customer\/changeAddress/,
        /\/customer\/changeKind/,
        /\/card\/add/,
        /\/customerBalance\/recharge/,
        /\/customerBalance\/rechargeWithVolume/,
        /\/customerBalance\/rechargeNotReport/,
        /\/card\/recharge/,
        /\/card\/faultTransfer/,

        /\/paymentRecord\/chargeFee/,

        /\/command\/clearError/,
        /\/command\/off/,
        /\/command\/on/,
        /\/command\/updateRepTime/,
        /\/command\/changeMeterNo/,
        /\/command\/delete/,
        /\/command\/forceTurnOn/,
        /\/command\/updateCount/,
        // 易信达业务API
        /\/rfYxdCard\/addRfCardAndRecharge/,
        /\/rfYxdCard\/yxdFaultTransfer/,
        /\/rfYxdCardRechargeRecord\/recharge/,
        /\/rfYxdCard\/faultTransfer/,
        // 集万讯业务API
        /\/rfJwxCard\/addRfCardAndRecharge/,
        /\/rfJwxCardRechargeRecord\/recharge/,
        /\/rfJwxCardRechargeRecord\/updateRecharge/,
        /\/rfJwxCard\/faultTransfer/,
        // AEP
        /\/iotAEPRecharge\/recharge/,
        /\/iotAEPRecharge\/rechargeWithVolume/,
        /\/iotAEPTransferRecord\/repairMeterData/,
        /\/iotAEPRecharge\/extraRecharge/,
        /\/xinchi\/iot/
    ];

    private icUrls: RegExp[] = [
        // IC卡读卡驱动API
        /\/api\/readCardType/,
        /\/api\/readCardData/,
        /\/api\/replacementCard/,
        /\/api\/buyWater/,
        /\/api\/createChangeCard/,
        /\/api\/createResetCard/,
        /\/api\/createCheckCard/,
        /\/api\/clearCardData/,
        /\/api\/createAccount/,
        // 集万讯读卡驱动API
        /\/api\/ReadRfCard/,
        /\/api\/WriteResetRFCard/,
        /\/api\/WriteConfigRFCard/,
        /\/api\/WriteSetTimeRFCard/,
        /\/api\/WriteCheckRFCard/,
        /\/api\/WriteRefundRFCard/,
        /\/api\/WriteConfigRFCardInternal/,
        /\/api\/WriteUserRFCard/
    ];

    private get msg(): NzMessageService {
        return this.injector.get(NzMessageService);
    }

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        for (const item of this.urls as RegExp[]) {
            if (item.test(req.url)) {
                const cashierHallId = this.getCashierHallId();
                if (cashierHallId) {
                    // 对请求的body进行处理
                    req = this.makeHallID(req, cashierHallId);
                    return next.handle(req);
                }
                const hc = this.injector.get(_HttpClient);
                if (hc) {
                    hc.cleanLoading();
                }
                return this.sendError(req);
            }
        }

        for (const item of this.icUrls as RegExp[]) {
            if (item.test(req.url)) {
                const cashierHallId = this.getCashierHallId();
                if (!cashierHallId) {
                    // 对请求的body进行处理
                    this.msg.error('没有营业厅信息，请确认是收费员进行操作，并选择一个营业厅！');
                    const hc = this.injector.get(_HttpClient);
                    if (hc) {
                        hc.cleanLoading();
                    }
                    return this.sendError(req);
                }
                return next.handle(req);
            }
        }

        return next.handle(req);
    }

    getCashierHallId(): number | string {
        const caSrv = this.injector.get(CacheService);
        const res = caSrv.get('hallCache', { mode: 'none' });
        return res.hallId ?? null;
    }

    // 获取并处理hallID
    makeHallID(req: HttpRequest<any>, hallId: string | number): HttpRequest<any> {
        return req.clone({
            body: { ...req.body, ...{ cashierHallId: hallId } }
        });
    }

    /**
     * 发出错误消息
     */
    sendError(req: HttpRequest<any>): Observable<any> {
        return new Observable((observer: Observer<HttpEvent<any>>) => {
            // 输出HALLID错误信息
            if (!environment.production) {
                console.log(`%c ${req.method}_WITH_HALLID_ERROR: ${req.url}`, `background:red;color:#fff`);
            }
            const res = new HttpResponse({
                status: 200,
                body: {
                    code: '0401',
                    message: '没有营业厅信息，请确认是收费员进行操作，并选择一个营业厅！'
                }
            });
            observer.next(res);
        });
    }
}
